package file;

import command.Cmd;
import common.ParseException;

import java.io.IOException;
import java.util.ArrayList;

public class Files {
    private static ArrayList<File> files = new ArrayList<File>();
    private static ArrayList<File> includeStak = new ArrayList<File>();
    private static ArrayList<File> includeFiles = new ArrayList<File>();
    private static ArrayList<File> dynamicFiles = new ArrayList<File>();

    public Files(String basePath) throws ParseException, IOException {
        java.io.File folder = new java.io.File(basePath);
        findFiles(folder);
        for (File file : files) {
            if ((file.getFileType() == FileType.PARSE || file.getFileType() == FileType.INCLUDE) && !file.isFileStringsParsed()) {
                includeStak.clear();
                includeStak.add(file);
                file.parse();
            }
            if((file.getFileType() == FileType.STATIC_PARSE || file.getFileType() == FileType.STATIC_INCLUDE) && !file.isFileStringsParsed())
                file.parse();
            if (file.getFileType() == FileType.PARSE || file.getFileType() == FileType.INCLUDE)
                dynamicFiles.add(file);
        }

        // Составляем список инклуд файлов для AutoStyle.css
        ArrayList<File> tFiles = new ArrayList<File>();
        for (File file : files) {
            if (file.getFileType() == FileType.PARSE || file.getFileType() == FileType.STATIC_PARSE)
                if (file.isAfterAll() || includeFiles.contains(Files.getFile(file.getFileAfter()))) {
                    includeFiles.add(file);
                    for (int i = 0; i < tFiles.size(); i++)
                        if (tFiles.get(i).isAfterAll() || includeFiles.contains(Files.getFile(tFiles.get(i).getFileAfter()))) {
                            includeFiles.add(tFiles.get(i));
                            tFiles.remove(i);
                            i--;
                        }
                } else {
                    tFiles.add(file);
                }
        }
    }

    void findFiles(java.io.File folder) throws ParseException, IOException {
        for (java.io.File f : folder.listFiles())
            if (f.isFile()) {
                if (f.getName().toLowerCase().endsWith(".mif"))
                    files.add(new File(f));
            } else if (f.isDirectory())
                findFiles(f.getAbsoluteFile());
    }

    public static ArrayList<File> getFiles() {
        return files;
    }

    public static File getFile(String alias) {
        for (File file : files)
            if (file.getFileType() != FileType.BAD && alias.equalsIgnoreCase(file.getFileAlias()))
                return file;
        return null;
    }

    public static void addIncludedFile(FileString fString, File file) throws ParseException {
        if (includeStak.contains(file)) {
            String str = "";
            for (File tFile : includeStak)
                str += tFile.getFileAlias() + " > ";
            str += file.getFileAlias() + " ";
            throw new ParseException(fString, "Обнаружено замыкание @includ'ов: " + str);
        }
        includeStak.add(file);
    }

    public static void removeIncludeFile(File file) {
        includeStak.remove(file);
    }

    public static void print() throws ParseException {
        System.out.println("\n\nAll files");
        for (File file : files) {
            System.out.println("  Alias:" + file.getFileAlias() + "  Name:" + file.getFullFileName());
            for (Cmd cmd : file.getCmds())
                print(4, cmd);
        }

        System.out.println("\n\nDynamic files");
        for (File file : dynamicFiles) {
            System.out.println("  Alias:" + file.getFileAlias() + "  Name:" + file.getFullFileName());
            for (Cmd cmd : file.getCmds())
                print(4, cmd);
        }

        System.out.println("\n\nIncluded files");
        for (File file : includeFiles) {
            System.out.println("  Alias:" + file.getFileAlias() + "  Name:" + file.getFullFileName());
            for (Cmd cmd : file.getCmds())
                print(4, cmd);
        }
    }

    public static ArrayList<File> getIncludeFiles()
    {
        return includeFiles;
    }

    private static void print(int tshift, Cmd cmd) {
        System.out.printf("%" + tshift + "s%s\n", "", cmd);
        for (Cmd tCmd : cmd.getBody())
            print(tshift + 2, tCmd);
    }
}
